package test;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.*;

import de.cau.apo.problems.identicalscheduling.ISInstance;



public class DynamicV2 {
	
	static int amountOfDifferentJobs =2;
	static double [] amountPerJob ={ 8.0, 6., 8.0}  ;
	static double [] jobSize={0.488 , 0.61 };
	static double newMakeSpan =1;
	static ArrayList<int []> A = new ArrayList<int []>();
	static int [] D;
	static ArrayList<int []> D_ArrayList;
	
	
	public static void main (String [] args){
		
		D = new int [10];
		for(int i = 1; i< D.length; i++)
			D[i] = Integer.MAX_VALUE;
		int [] adf = {8,6,8};
		for(int i = 0; i< 9; i++)
			for(int j = 0; j< 7; j++)
				for(int k = 0; k < 9; k++){
				adf[0] = i;
				adf[1] = j;
				adf[2] = k;
				if( kruemelMonster(adf,amountPerJob) == 330)
					System.out.println( "i:" +i+ ",j: "+ j+",k: " +k );
		System.out.print(kruemelMonster(adf,amountPerJob) +", ");
				}

/*
		initialize(2, 0., new LinkedList<Integer>());
		printConfig(A);
		solveDynamicProgram(2,new LinkedList<Integer>());
		System.out.println("Es werden "+ D[D.length-1] + " Bins benötigt." );
		for(int i = 0; i < D.length;i++){
			System.out.print(D[i] + ", ");
		}
		*/
	}
	
	public static void initialize(int m, double wert, LinkedList<Integer> tupel){
		
		if(m == 0){
			
			if(wert < newMakeSpan){
				//speicher das Tupel
				Integer [] help = (Integer[]) tupel.toArray( new Integer[tupel.size()] );
				A.add(toPrimitive(help));	
				
				
				// setze Wert an der Stelle gleich 1
				D[kruemelMonster(toPrimitive(help),amountPerJob)] = 1 ;
			}
			
		}else{
			
			//noch den Fall amountPerJop = 0 betrachten...
			if(amountPerJob[amountOfDifferentJobs -m] == 0){
				tupel.add(0);
				initialize(m-1, wert ,tupel);
				tupel.removeLast();
			}else{
				
			for(int i=0; i < amountPerJob[amountOfDifferentJobs -m] + 1; i++){
				tupel.add(i);
				initialize(m-1, wert + (i*jobSize[amountOfDifferentJobs-m]),tupel);
				tupel.removeLast();
			}
			}
		}
	}
	
	
	public static void solveDynamicProgram(int m, LinkedList<Integer> tupel){
		
		if(m == 0){
				//speicher das Tupel
				Integer [] help = (Integer[]) tupel.toArray( new Integer[tupel.size()] );
				
				// Bestimme den naechsten Wert

				D[kruemelMonster(toPrimitive(help),amountPerJob)] =  findMin(toPrimitive(help));
				
				
			}else{
			
				if(amountPerJob[amountOfDifferentJobs -m] == 0){
					tupel.add(0);
					solveDynamicProgram(m-1 ,tupel);
					tupel.removeLast();
				}else{
		
			for(int i=0; i < amountPerJob[amountOfDifferentJobs -m]+1; i++){
				tupel.add(i);
				solveDynamicProgram(m-1,tupel);
				tupel.removeLast();
			}
			}
		}
	}
	
	public static int findMin(int [] j ){
		Iterator<int []> it = A.iterator();
		int[] c= new int[j.length];
		int min = Integer.MAX_VALUE;
		while(it.hasNext()){
			int [] a = it.next();
			boolean b = true;
			for(int i = 0; i< j.length; i++){
				if(a[i] > j[i])
					b = false;
			}
			if(b){
				for(int i =0; i < a.length;i++ )
					c[i] = j[i]- a[i];
				min = Math.min(min, 1+D[kruemelMonster(c,amountPerJob)]);
			}
			
			
		}
		return min;
		
	}
		
	
 	public static void readData(String path, double delta, double makeSpan){
		ISInstance instanz = new ISInstance();
		try {
			if(instanz.parseInstance("INSTANCES/NU_1_0010_05_1.txt"))
			{
				delta = 0.25;
			    makeSpan = 200;
			    amountPerJob = null;	
			    newMakeSpan= makeSpan;
			    amountOfDifferentJobs = amountPerJob.length;
			    
			    jobSize = new double [amountPerJob.length];
			    for(int i = 0; i < jobSize.length; i++)
			    	jobSize[i] = delta * Math.pow((1+delta), i);
			 
			    int dLength =1;
			    for(int i = 0; i< amountPerJob.length;i++)
			    	dLength = (int)(dLength *amountPerJob[i]);
			    D = new int [dLength];
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static int[] toPrimitive(Integer[] IntegerArray) {
		 
		int[] result = new int[IntegerArray.length];
		for (int i = 0; i < IntegerArray.length; i++) {
			result[i] = IntegerArray[i].intValue();
		}
		return result;
	}
	
	public static void printConfig ( ArrayList<int []> a){
		
		for(int i = 0; i< a.size(); i++){
			for(int j = 0 ; j < a.get(i).length; j++)
				System.out.print(a.get(i)[j]+ ", ");
		System.out.println();
		}
	}
	
	public static int kruemelMonster (int [] tupel , double [] amount){
		 
		int pos = 0;
		int multiplikator = 1;
		for(int i =tupel.length-1; i> -1;i --){
			pos = pos +tupel[i]*multiplikator;
			multiplikator = multiplikator * ((int)amount[i]+1);
		}
		
		
		
		return pos;
	}

}
